package com.dongdongshop.controller;

import com.alibaba.dubbo.common.utils.StringUtils;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSONObject;
import com.dongdongshop.constant.HttpResultEnum;
import com.dongdongshop.data.DataResult;
import com.dongdongshop.pojo.cart.Cart;
import com.dongdongshop.pojo.item.TbItem;
import com.dongdongshop.pojo.user.TbUser;
import com.dongdongshop.service.cart.CartService;
import com.dongdongshop.service.item.ItemServiceI;
import com.dongdongshop.util.CookieUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * 购物车
 */
@Controller
@RequestMapping("cart")
public class CartController {

    private static final Logger log = LoggerFactory.getLogger(CartController.class);

    @Reference(check = false)
    private CartService cartService;

    @Reference(check = false)
    private ItemServiceI itemService;

    @Autowired
    private RedisTemplate redisTemplate;

    /*
    * 判断用户是否登录，登录就从redis中获取，未登录就从cookie中获取购物车
    * Cart代表一个商家购物车   List<Cart>那就代表整个购物车页面了 可理解为一个大的购物车
    * */
    @RequestMapping("getCart")
    @ResponseBody
    public List<Cart> getCart(HttpServletRequest request,HttpServletResponse response) {
        //从shiro中取出登录用户
        Subject subject = SecurityUtils.getSubject();
        TbUser user = (TbUser) subject.getPrincipal();
        //判断用户是否登录 user是否=null
        List<Cart> cartsRedis;
        if (user == null) {
            //如果未登录从cookie中获取购物车
            //1、使用cookie工具类从cookie中取出购物车(List<Cart>大购物车)
            String cartList = CookieUtils.getCookieValue(request, "cartList", "UTF-8");
            //判断购物车是否为空，如果为空赋值空数组（可能该用户没有在cookie中存储过商品，如果为null的话后面转换错误，所以赋值空数组）
            if (StringUtils.isBlank(cartList)) {
                cartList = "[]";
            }
            //将cartList解析成list集合实体
            List<Cart> cartsCookie = JSONObject.parseArray(cartList, Cart.class);
            return cartsCookie;
        } else {
            //登录就从redis中取出购物车
            cartsRedis = cartService.getCartsByUserNameForRedis(user.getUsername());
            //取出cookie中的购物车
            String cartCookieStr = CookieUtils.getCookieValue(request, "cartList", "UTF-8");
            List<Cart> cartsCookie = JSONObject.parseArray(cartCookieStr, Cart.class);
            //cookie中有购物车的情况下才进行合并
            if (cartsCookie != null && cartsCookie.size() > 0) {
                System.out.println(cartsCookie);
                //将cookie购物车的数据和redis中购物车的数据进行合并，返回合并完成的购物车
                List<Cart> mergeCartList = cartService.mergeCartList(cartsRedis, cartsCookie);
                //合并完成后清除cookie中的数据
                CookieUtils.deleteCookie(request, response, "cartList");
                //将合并后的数据保存到redis中
                cartService.saveCartListToRedis(mergeCartList, user.getUsername());
                //返回合并后的
                return mergeCartList;
            }
        }
        //cookie没数据就直接返回redis的购物车
        return cartsRedis;
    }

    /*
    * 点击商品添加到购物车(添加到cookie或者redis)
    * */
    @RequestMapping("addGoodsToCartList")
    public String addGoodsToCartList(HttpServletRequest request, HttpServletResponse response, Long itemId, Integer num, Model model){
        try {
            log.info("进入添加商品到购物车方法，商品ID：{}，商品数量：{}",itemId,num);
            //cookie不能直接往里面增加商品，会把原来的给覆盖掉
            //1、调用封装方法去查询cookie或者redis中的购物车。集合中是每个商家购物车
            List<Cart> cartList = getCart(request,response);
            // 2、调用购物车服务   往大购物车中添加用户添加的商品信息
            //将cookie中原先的数据也发送过去，因为如果直接往cookie中增加会覆盖原来的，所以需要让购物车服务将原来的和新的进行组装然后返回
            //所以返回回来的数据可以直接是新的和旧的数据组装到一起的list，所以返回值可以直接覆盖原先的List<Cart> cartList集合
            log.info("执行调用购物车服务【添加商品到购物车集合并重新组装】.....");
            cartList = cartService.addGoodsToCartList(cartList,itemId,num);
            //从shiro中取出登录用户
            Subject subject = SecurityUtils.getSubject();
            TbUser user = (TbUser)subject.getPrincipal();
            //如果用户没登陆存入cookie
            if(user==null){
                //3、将大购物车对象集合写入cookie   cookieMaxage：该参数为cookie的存活时间，单位分钟，60分钟*24*7=7天
                CookieUtils.setCookie(request,response,"cartList", JSONObject.toJSONString(cartList),60*24*7,"UTF-8");
                log.info("购物车数据成功存入cookie..");
            }else {  //登录就保存redis
                cartService.saveCartListToRedis(cartList,user.getUsername());
            }
            //根据itemId查询该商品信息
            TbItem item = itemService.getItemByItemId(itemId);
            model.addAttribute("item",item);
        }catch (Exception e){
            log.error("添加商品到购物车异常",e);
        }
        //跳转购物车页面
        return "cart/successCart";
    }
    /*
    * 获取该用户的购物车并返回购物车页面
    * */
    @RequestMapping("toCartList")
    public String toCartList(HttpServletRequest request,Model model){
        //从shiro中取出登录用户
        Subject subject = SecurityUtils.getSubject();
        TbUser user = (TbUser)subject.getPrincipal();
        if(user==null){
            String cartList = CookieUtils.getCookieValue(request, "cartList", "UTF-8");
            List<Cart> cartsCookie = JSONObject.parseArray(cartList, Cart.class);
            model.addAttribute("cartList",cartsCookie);
        }else {
            //登录就从redis中取出购物车
            List<Cart> cartsRedis = cartService.getCartsByUserNameForRedis(user.getUsername());
            model.addAttribute("cartList",cartsRedis);
        }
        return "cart/cartList";
    }
    /*
    * 删除购物车中的商品明细
    * */
    @RequestMapping("delCartOrderItem")
    @ResponseBody
    public DataResult delCartOrderItem(Long itemId, HttpServletRequest request, HttpServletResponse response){
        //从shiro中取出登录用户
        Subject subject = SecurityUtils.getSubject();
        TbUser user = (TbUser)subject.getPrincipal();
        //判断用户当前是否时登录状态
        if(user==null){
            //如果没登陆就删除cookie中的商品
            //使用cookie工具类从cookie中取出购物车(List<Cart>大购物车)
            String cartList = CookieUtils.getCookieValue(request, "cartList", "UTF-8");
            //将cartList解析成list集合实体
            List<Cart> cartsCookie = JSONObject.parseArray(cartList, Cart.class);
            //调用购物车服务进行删除
            cartsCookie = cartService.deleteCartOrderItem(cartsCookie,itemId);
            if(cartsCookie == null || cartsCookie.size() <= 0){
                //重新放入cookie
                CookieUtils.setCookie(request,response,"cartList","[]",60*24*7,"UTF-8");
            }else {
                //重新放入cookie
                CookieUtils.setCookie(request,response,"cartList", JSONObject.toJSONString(cartsCookie),60*24*7,"UTF-8");
            }
        }else {
            //登录时获取redis中所有数据
            List<Cart> cartsRedis = cartService.getCartsByUserNameForRedis(user.getUsername());
            //调用购物车服务删除该商品并返回新购物车
            List<Cart> carts = cartService.deleteCartOrderItem(cartsRedis, itemId);
            //存入redis
            cartService.saveCartListToRedis(carts,user.getUsername());
        }
        return new DataResult(HttpResultEnum.SUCCESS.getCode(),HttpResultEnum.SUCCESS.getMessage());
    }
}
